﻿using System.Collections.Generic;
using System.Linq;
using IGM.DataProvider;
using IGM.Framework.Constants;

namespace IGM.Business
{
    public partial class Business
    {
        #region -- Get Group --

        public List<Group> GetListGroupByMajorId(int majorId)
        {
            return DataContex != null && majorId > 0
                        ? DataContex.Groups.Where(m => m.IdMajor == majorId).ToList() : null;
        }

        /// <summary>
        /// This function shows list of Student.
        /// </summary>
        /// <returns></returns>
        public List<Group> GetListGroupByKindInternId(int kindinternId, int majorId)
        {
            if (DataContex == null || kindinternId <= 0 || majorId <=0) return null;

            return DataContex.Groups.Where(m => m.IdKindIntern == kindinternId && m.IdMajor == majorId).ToList();
        }

        public List<Group> GetListGroupwithoutGroup(int oldGroup)
        {
            return DataContex != null && oldGroup > 0
                       ? DataContex.Groups.Where(m => m.Id != oldGroup).ToList() : null;
        }
        
        #endregion

        #region Common

        private static bool GroupCommonValidator(Group group, out string message)
        {
            if (string.IsNullOrWhiteSpace(group.Name))
            {
                message = string.Format(ConstantMessages.RequireFieldIsBlank, "tên Nhóm");
                return false;
            }

            if (group.Name.Length >= 50)
            {
                message = string.Format(ConstantMessages.FieldDataOverMaxLength, "tên Nhóm", 50);
                return false;
            }

            if (group.NumberMembers < 0)
            {
                message = string.Format(ConstantMessages.DataUnderMinValue, "số lượng thành viên");
                return false;
            }
            message = string.Empty;
            return true;
        }

        #endregion

        #region -- Add Group --

        /// <summary>
        /// 
        /// </summary>
        /// <param name="group"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public bool AddGroupValidator(Group group, out string message)
        {
            if (!GroupCommonValidator(group, out message)) return false;

            if (DataContex.Groups.Any(f => f.Name.ToLower() == group.Name.ToLower()))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, group.Name);
                return false;
            }

            return true;
        }

        /// <summary>
        /// This function add a new facutly into list.
        /// </summary>
        public void AddGroup(Group group)
        {
            DataContex.Groups.AddObject(group);
            DataContex.SaveChanges();
        }

        public void AddGroup(List<Group> groups)
        {
            foreach (var group in groups)
            {
                DataContex.Groups.AddObject(group);
            }
            DataContex.SaveChanges();
        }

        #endregion

        #region -- Edit Group --


        public bool EditGroupValidator(Group group, out string message)
        {
            var id = group.Id;

            if (!GroupCommonValidator(group, out message)) return false;

            if (DataContex.Groups.Any(m => m.Name.ToLower() == group.Name.ToLower() && m.Id != id))
            {
                message = string.Format(ConstantMessages.ItemIsExisted, group.Name);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="group"></param>
        /// <returns></returns>
        public bool EditGroup(Group group)
        {
            var id = group.Id;
            var updateGroup = DataContex.Groups.SingleOrDefault(f => f.Id == id);

            if (updateGroup == null)
                return false;

            updateGroup.Name = group.Name;
            updateGroup.IdKindIntern = group.IdKindIntern;
            updateGroup.NumberMembers = group.NumberMembers;
            updateGroup.Project = group.Project;

            DataContex.SaveChanges();
            return true;
        }

        #endregion

        #region -- Delete Group --

        public bool DeleteGroupsValidator(IEnumerable<Group> groups, out string message)
        {
            const string intialize = "Nhóm: ";
            var itemsCannotIdentify = (from group1 in groups
                                       let id = group1.Id
                                       where !DataContex.Groups.Any(m => m.Id == id)
                                       select group1).Aggregate(intialize, (current, group1) => current + (group1.Name + ", "));

            if (itemsCannotIdentify != intialize)
            {
                message = string.Format(ConstantMessages.SomeItemsCanNotIdentify, itemsCannotIdentify.TrimEnd(','));
                return false;
            }

            var itemsInUse = (from group1 in groups
                              let id = group1.Id
                              where DataContex.GroupStudents.Any(m => m.IdGroup == id) || DataContex.GroupLecturers.Any(m => m.IdGroups == id)
                              select group1).Aggregate(intialize, (current, group1) => current + (group1.Name + ", "));

            if (itemsInUse != intialize)
            {
                message = string.Format(ConstantMessages.SomeItemsInUseCanNotDelete, itemsInUse.TrimEnd(','));
                return false;
            }

            message = string.Empty;
            return true;
        }

        /// <summary>
        /// Delete object
        /// </summary>
        public void DeleteGroups(List<Group> groups)
        {
            for (var i = groups.Count - 1; i >= 0; i--)
            {
                var id = groups[i].Id;
                var deleteGroup = DataContex.Groups.Single(m => m.Id == id);

                // Delete GroupStudent
                var deleteGStudent = DataContex.GroupStudents.Where(m => m.IdGroup == id).ToList();
                for (var index = deleteGStudent.Count - 1; index >= 0; index--)
                {
                    var idGroupStudent = deleteGStudent[index].Id;
                    var deleteGroupStudent = DataContex.GroupStudents.Single(m => m.Id == idGroupStudent);
                    DataContex.GroupStudents.DeleteObject(deleteGroupStudent);
                }

                // Delete GroupLecturer
                var deleteGLecturer = DataContex.GroupLecturers.Where(m => m.IdGroups == id).ToList();
                for (var index = deleteGLecturer.Count - 1; index >= 0; index--)
                {
                    var idGroupLecturer = deleteGLecturer[index].Id;
                    var deleteGroupLecturer = DataContex.GroupLecturers.Single(m => m.Id == idGroupLecturer);
                    DataContex.GroupLecturers.DeleteObject(deleteGroupLecturer);
                }


                // Delete Subcommittee Group
                var deleteGSubcommittee = DataContex.SubcommitteeGroups.Where(m => m.IdGroup == id).ToList();
                for (var index = deleteGSubcommittee.Count - 1; index >= 0; index--)
                {
                    var idSubcommitteeGroup = deleteGSubcommittee[index].Id;
                    var deleteSubcommitteeGroup = DataContex.SubcommitteeGroups.Single(m => m.Id == idSubcommitteeGroup);
                    DataContex.SubcommitteeGroups.DeleteObject(deleteSubcommitteeGroup);
                }

                DataContex.Groups.DeleteObject(deleteGroup);
            }
            DataContex.SaveChanges();
        }

        public void ClearOldData(int kindinterId)
        {
            var deleteGroups = DataContex.Groups.Where(m => m.IdKindIntern == kindinterId).ToList();

            DeleteGroups(deleteGroups);         
        }

        #endregion
       
    }
}